package com.hui.security.sys.controller;

import com.hui.security.common.jwt.JwtUtil;
import com.hui.security.common.response.ResultMapper;
import com.hui.security.common.response.ResultVO;
import com.hui.security.common.util.AESUtil;
import com.hui.security.sys.dto.UserAccessToken;
import com.hui.security.sys.entity.Permission;
import com.hui.security.sys.entity.Role;
import com.hui.security.sys.entity.User;
import com.hui.security.sys.exception.ExceptionEnum;
import com.hui.security.sys.exception.HSecurityException;
import com.hui.security.sys.service.PermissionService;
import com.hui.security.sys.service.RoleService;
import com.hui.security.sys.service.UserService;
import com.hui.security.sys.vo.LoginVO;
import com.hui.security.sys.vo.UserVO;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import lombok.extern.slf4j.Slf4j;
import org.apache.shiro.authz.annotation.RequiresRoles;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.MediaType;
import org.springframework.validation.BindException;
import org.springframework.validation.BindingResult;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.*;

import java.io.UnsupportedEncodingException;
import java.util.List;

/**
 * <b><code>UserController</code></b>
 * <p/>
 * Description:
 * <p/>
 * <b>Creation Time:</b> 2019/1/3 23:56.
 *
 * @author HuWeihui
 */
@RestController
@RequestMapping("/v1/sys")
@Api(value = "用户模块-用户API", tags = "users")
@Slf4j
public class UserController {

    /**
     * The User service.
     */
    @Autowired
    private UserService userService;


    /**
     * User login result vo.
     *
     * @param loginVO the login vo
     * @param result  the result
     * @return the result vo
     * @author HuWeihui
     * @since hui_project v1
     */
    @ApiOperation(value = "用户登录", produces = MediaType.APPLICATION_JSON_UTF8_VALUE)
    @PostMapping("/user/login")
    public ResultVO userLogin(@RequestBody @Validated LoginVO loginVO, BindingResult result) {
        User user = userService.userLogin(loginVO);
        //查询用户是否存在
        if (null == user) {
            throw new HSecurityException(ExceptionEnum.SECURITY_ERROR_USER_NOT_EXIST);
        }
        //加密后的密码
        String encryptPassword = AESUtil.encrypt(loginVO.getUserAccount(), loginVO.getUserPassword());
        //密码不正确
        if (!user.getUserPassword().equals(encryptPassword)) {
            throw new HSecurityException(ExceptionEnum.SECURITY_ERROR_PASSWORD_INCORRECT);
        }
        //密码正确则生成token返回给用户
        UserAccessToken userAccessToken = new UserAccessToken();
        try {
            //生成token
            String token = JwtUtil.sign(user.getUserAccount(), encryptPassword);
            BeanUtils.copyProperties(user, userAccessToken);
            userAccessToken.setAccessToken(token);
        } catch (UnsupportedEncodingException e) {
            throw new HSecurityException("生成token失败");
        }
        return ResultMapper.ok(userAccessToken);
    }

    /**
     * User log out result vo.
     *
     * @param result the result
     * @return the result vo
     * @author : Hu weihui
     * @since nile -cmszbs-szcst 0.1.0
     */
    @ApiOperation(value = "用户登出", produces = MediaType.APPLICATION_JSON_UTF8_VALUE)
    @PostMapping("/user/logout")
    public ResultVO userLogOut(BindingResult result) {
        return ResultMapper.ok();
    }

    /**
     * Create user result vo.
     *
     * @param userVO the user vo
     * @param result the result
     * @return the result vo
     * @throws BindException the bind exception
     * @author HuWeihui
     * @since hui_project v1
     */
    @ApiOperation(value = "创建用户", produces = MediaType.APPLICATION_JSON_UTF8_VALUE)
    @PostMapping("/user/{id}")
    public ResultVO createUser(@RequestBody @Validated UserVO userVO, BindingResult result) throws BindException {
        if (result.hasErrors()) {
            throw new BindException(result);
        }
        User user = new User();
        BeanUtils.copyProperties(userVO, user);
        return ResultMapper.ok(userService.add(user));
    }

    /**
     * Delete user result vo.
     *
     * @param userId the user id
     * @return the result vo
     * @author HuWeihui
     * @since hui_project v1
     */
    @ApiOperation(value = "删除用户", produces = MediaType.APPLICATION_JSON_UTF8_VALUE)
    @DeleteMapping("/user/{id}")
    public ResultVO deleteUser(String userId) {
        userService.delete(userId);
        return ResultMapper.ok();
    }

    /**
     * Update user result vo.
     *
     * @param userVO the user vo
     * @param result the result
     * @return the result vo
     * @author HuWeihui
     * @since hui_project v1
     */
    @ApiOperation(value = "更新用户", produces = MediaType.APPLICATION_JSON_UTF8_VALUE)
    @PutMapping("/users")
    public ResultVO updateUser(@RequestBody @Validated UserVO userVO, BindingResult result) {
        User user = new User();
        BeanUtils.copyProperties(userVO, user);
        userService.update(user);
        return ResultMapper.ok();
    }

    /**
     * Gets user.
     *
     * @param userId the user id
     * @return the user
     * @author HuWeihui
     * @since hui_project v1
     */
    @ApiOperation(value = "查询用户详情", produces = MediaType.APPLICATION_JSON_UTF8_VALUE)
    @GetMapping("/user/{id}")
    @RequiresRoles("user")
    public ResultVO getUser(@PathVariable("id") String userId) {
        User user = userService.get(userId);
        return ResultMapper.ok(user);
    }



    /**
     * List users result vo.
     *
     * @param appId the application id
     * @param groupName     the group name
     * @param userName      the user name
     * @return the result vo
     * @author : Hu weihui
     * @since hui_project v1
     */
    @ApiOperation(value = "查询用户列表", produces = MediaType.APPLICATION_JSON_UTF8_VALUE)
    @GetMapping("/users")
    public ResultVO listUsers(@RequestParam String appId, @RequestParam String groupName, @RequestParam String userName) {
        return ResultMapper.ok();
    }

    /**
     * Gets group users.
     *
     * @param groupId the group id
     * @return the group users
     * @author : Hu weihui
     * @since hui_project v1
     */
    @ApiOperation(value = "查询用户组下的用户")
    @GetMapping("/group/{id}/users")
    public ResultVO getGroupUsers(@PathVariable("id")String groupId){
        List<User> users = userService.listByGroupId(groupId);
        return ResultMapper.ok(users);
    }

}
